<?php
include "chooseOneStock.php";
// 参数定义
// $train_fenxi = array();
$train_fenxi;
$history = array();     // 记录历史明细
$AllHistory = array();
$AllLineChart = array();
$AllBingTu = array();
$AllarrayCalDay = array();
$bing_json_string;
$orderRule;  // 排序规则
@$orderRule = $_REQUEST["order"];   // 排序规则
@$HoldLimit = $_REQUEST["holdlimit"];  // 持股上限
@$Sta_Test = $_REQUEST["sta_test"];    // 测试集开始时间
@$End_Test = $_REQUEST["end_test"];       // 测试集结束时间
@$DayBuy = $_REQUEST["one_buy"];       // 单日买入数
@$KeepHoldProfit = $_REQUEST["zhi_ying_rate"];       // 止盈收益率
@$HighestFall = $_REQUEST["max_huiluo"];       // 最大回落
@$StopLoseProfit = $_REQUEST["zhi_Sun"];       // 止损收益率
@$source = $_REQUEST["holdtime"];
//利用 explode 函数分割字符串到数组
$holdtime = explode(',', $source);
$hold_time_array = array();
for ($index = 0; $index < count($holdtime); $index++) {
    array_push($hold_time_array, intval($holdtime[$index]));
}
@$compareWay = $_REQUEST["compareWay"];    // 指数
@$increment = $_REQUEST["increment"]; // 增量值


/**
 * 根据增量num获取starttime前的日期
 */
function getDateByCur($StartTime, $Num)
{
    global $TradeDate;
    while (array_search($StartTime, $TradeDate) == null) {
        $time = strtotime($StartTime);
        $StartTime = date("Y-m-d", strtotime("+1 day", $time));
    }
    $cur = array_search($StartTime, $TradeDate);
    $StartTime = $TradeDate[$cur - $Num];
    return $StartTime;
}

/**
 * 根据增量num获取starttime前的日期
 */
function getDateByCur_After($StartTime, $Num)
{
    global $TradeDate;
    while (array_search($StartTime, $TradeDate) == null) {
        $time = strtotime($StartTime);
        $StartTime = date("Y-m-d", strtotime("+1 day", $time));
    }
    $cur = array_search($StartTime, $TradeDate);
    $StartTime = $TradeDate[$cur + $Num];
    return $StartTime;
}


/**
 * 根据回测时间获取最佳参数，如：5天是最好的情况
 */
function oneTest($Sta_Test, $End_Test, $hold_time_array, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, $AddBorder)
{
    $train_ana = array();                        // 保存参数
    $hold_time_count = count($hold_time_array);  // 持股周期的集合
    while (1) {
        
        for ($i = 0; $i < $hold_time_count; $i++) {
            // 根据不同的持股时间进行回测
            $One_HoldLimit_Trade = oneActionMore($Sta_Test, $End_Test, $hold_time_array[$i], $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, NULL);
            // var_dump($One_HoldLimit_Trade);
            if (count($One_HoldLimit_Trade) < 3) { // 如果回测的股票数量小于一定程度，认为算不出指标，所以设计如此
                $Sta_Test = getDateByCur($Sta_Test, 5);  // 往前增量，重新设置时间
                $i = 0;                                  // 重新回测
                $train_ana = (array)null;                // 结果集置空
                $trade_analysis = (array)null;           // 结果集置空
                break;                                   // 跳出
            }

            $trade_analysis = calTarget($One_HoldLimit_Trade, $hold_time_array[$i],$HoldLimit,$Sta_Test,$End_Test,null);
            array_push($train_ana, $trade_analysis);    // 将所有的分析结果保存      
        }
        if ($i == $hold_time_count)  // 如果所有的持股周期的情况都测试了，那么可以跳出大循环
        {
            break;
        }
    }
    sort_array_of_array_desc($train_ana, "real_shouyilv");  // 根据收益率排序
    $result = $train_ana[0];                                // 获取最好的那种持股周期
    $result["starttime"] = $Sta_Test;
    $result["endtime"] = $End_Test;
    return $result;
}

/**
 * 进行训练回测 返回最后的测试选定的参数
 */
function incremenOne($Sta_Test, $hold_time_array, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, $AddBorder, $increment)
{
    $his_target;
    $be = getDateByCur($Sta_Test, 20);      // 首次训练，往前看一个月（20天），其实有必要验证20天一定能拿到股票
    // 第一次训练获取最好持股周期
    $one =  oneTest($be, $Sta_Test, $hold_time_array, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, NULL);
    $his_target[] = $one;
    $be = $one["starttime"];                // 第二次训练的结束时间 == 第一次训练的开始时间

    $be  = getDateByCur($be, $increment);   // 增量往前看，获取第二次训练的开始时间 
    // 第二次训练获取最好持股周期
    $two = oneTest($be, $Sta_Test, $hold_time_array, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, NULL);
    $his_target[] = $two;                  // 第一次训练获取最好持股周期
    $be = $two["starttime"];               // 第n次训练的结束时间 == 第n+1次训练的开始时间

    // 进行m次训练获取最好持股周期，直到结束为止
    while (abs($one["holdtime"] - $two["holdtime"]) < 5) {
        $one = (array)null;                    // 结果集置空
        $be  = getDateByCur($be, $increment);  // 增量往前看，获取第n次训练的开始时间 
        // 第n次训练获取最好持股周期
        $one = oneTest($be, $Sta_Test, $hold_time_array, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, NULL);
        $his_target[] = $one;                  // 保存结果集
        $be = $one["starttime"];               // 第n次训练的结束时间 == 第n+1次训练的开始时间
        // 下面的条件判断是为了比较第二次与第三次的训练
        if (abs($one["holdtime"] - $two["holdtime"]) >= 5) {
            break;
        }
        $two = (array)null;                    // 第n次的结果集置空
        $be  = getDateByCur($be, $increment);  // 增量往前看，获取第n+2次训练的开始时间
        $two = oneTest($be, $Sta_Test, $hold_time_array, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, NULL);
        $his_target[] = $two;
        $be = $two["starttime"];               // 第n+1次训练的结束时间 == 第n+2次训练的开始时间
    }
    $cur = count($his_target) - 1;
    $test_parm = $his_target[$cur];
    return $test_parm;
}


if ($Sta_Test != null && $End_Test != null) {  // 时间不为空
    // 开始测试



     // $re1 = oneTest("2016-01-10", "2016-03-20", $hold_time_array, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, NULL);
    // var_dump($re1);
    var_dump('开始时间'.$Sta_Test);
    $his_target = incremenOne($Sta_Test, $hold_time_array, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, NULL, $increment);
    var_dump($his_target);  // 得到最好的天数
    $hold_time_parm = $his_target["holdtime"];  // 最好天数

    $incre_time = getDateByCur_After($Sta_Test, $hold_time_parm);
    var_dump($incre_time);
    $One_Trade = oneActionMore($Sta_Test, $incre_time, $hold_time_parm, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, NULL);
    $left = leftMore($Sta_Test, $incre_time, $One_Trade);         // 第一次测试回测的剩余持仓
    var_dump($One_Trade);
    var_dump($Sta_Test);
    var_dump($incre_time);
    $left_amount = calculate_caption($One_Trade,$HoldLimit,$Sta_Test, $incre_time,null);
    $left_amount = $left_amount["two"];
    var_dump($left);
    var_dump($left_amount);

    if ($One_Trade != null) {
            $trade_analysis = calTarget($One_Trade, $hold_time_parm,$HoldLimit,$Sta_Test, $incre_time,null);  // 计算第一次测试回测指标
    
            $trade_analysis["starttime"] = $Sta_Test;                  // 添加时间字段
            $trade_analysis["endtime"] = $incre_time;                  // 添加时间字段
            $trade_analysis["trainstart"] = $his_target["starttime"];  // 添加时间字段
            $trade_analysis["trainend"] = $his_target["endtime"];      // 添加时间字段
            $trade_analysis["train_shouyi"] = $his_target["year_shouyi"];// 添加时间字段
            $all_traget[] = $trade_analysis;                           // 保存指标
    }
    var_dump($trade_analysis);

    // 第一次循环
    
    var_dump($End_Test);
    //while ($incre_time < $End_Test) {        // 第n次的测试回测的结束时间<输入的测试回测结束时间 
        var_dump($incre_time); 
        //var_dump($incre_time < $End_Test);       

        $his_target = (array)null;           // 结果集置空
        $Sta_Test = $incre_time;             // 下一次训练的结束时间==下一次测试的开始时间
        // 获取第n次训练最佳指标
        $his_target = incremenOne($Sta_Test, $hold_time_array, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, NULL, $increment);
        $hold_time_parm =  $his_target["holdtime"];                    // 获取第n次训练最佳持股时间
        $incre_time = getDateByCur_After($Sta_Test, $hold_time_parm);  // 第n次的测试回测：结束时间

        $One_Trade  = (array)null;           // 第n-1次的结果集置空
        // 进行第n次的测试回测
        $One_Trade = oneActionMore($Sta_Test, $incre_time, $hold_time_parm, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, $left);
        $left = (array)null;
        $left = leftMore($Sta_Test, $incre_time, $One_Trade);         // 第n次测试回测的剩余持仓
        ////////////////////////////////
        $temp_amount = calculate_caption($One_Trade,$HoldLimit,$Sta_Test, $incre_time,$left_amount);
        $temp_amount = $temp_amount["two"];
        var_dump($left);
        var_dump($temp_amount);
        $left_amount = (array)null;   // 
        $left_amount = $temp_amount;
        $temp_amount = (array)null;
        ////////////////////////
        $trade_analysis = (array)null;       // 第n-1次的结果集置空
        if ($One_Trade != null)           // 需要有股票才进行投资
        {
            
            $trade_analysis = calTarget($One_Trade, $hold_time_parm,$HoldLimit,$Sta_Test, $incre_time,null);
            $trade_analysis["starttime"] = $Sta_Test;
            $trade_analysis["endtime"] = $incre_time;
            $trade_analysis["trainstart"] = $his_target["starttime"];  // 添加时间字段
            $trade_analysis["trainend"] = $his_target["endtime"];      // 添加时间字段
            $trade_analysis["train_shouyi"] = $his_target["year_shouyi"];// 添加时间字段
            $all_traget[] = $trade_analysis;
            ///////////////////////////////////
            $left_amount = (array)null;
            //////////////////////////
        } 
        var_dump($trade_analysis);
    
    // // 第二次循环
    // var_dump($incre_time); 
    //     //var_dump($incre_time < $End_Test);       

    //     $his_target = (array)null;           // 结果集置空
    //     $Sta_Test = $incre_time;             // 下一次训练的结束时间==下一次测试的开始时间
    //     // 获取第n次训练最佳指标
    //     $his_target = incremenOne($Sta_Test, $hold_time_array, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, NULL, $increment);
    //     $hold_time_parm =  $his_target["holdtime"];                    // 获取第n次训练最佳持股时间
    //     $incre_time = getDateByCur_After($Sta_Test, $hold_time_parm);  // 第n次的测试回测：结束时间

    //     $One_Trade  = (array)null;           // 第n-1次的结果集置空
    //     // 进行第n次的测试回测
    //     $One_Trade = oneActionMore($Sta_Test, $incre_time, $hold_time_parm, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, $left);
    //     $left = (array)null;
    //     $left = leftMore($Sta_Test, $incre_time, $One_Trade);         // 第n次测试回测的剩余持仓
    //     ////////////////////////////////
    //     $temp_amount = calculate_caption($One_Trade,$HoldLimit,$Sta_Test, $incre_time,$left_amount);
    //     $temp_amount = $temp_amount["two"];
    //     var_dump($left);
    //     var_dump($temp_amount);
    //     $left_amount = (array)null;   // 
    //     $left_amount = $temp_amount;
    //     $temp_amount = (array)null;
    //     ////////////////////////
    //     $trade_analysis = (array)null;       // 第n-1次的结果集置空
    //     if ($One_Trade != null)           // 需要有股票才进行投资
    //     {
            
    //         $trade_analysis = calTarget($One_Trade, $hold_time_parm,$HoldLimit,$Sta_Test, $incre_time,null);
    //         $trade_analysis["starttime"] = $Sta_Test;
    //         $trade_analysis["endtime"] = $incre_time;
    //         $trade_analysis["trainstart"] = $his_target["starttime"];  // 添加时间字段
    //         $trade_analysis["trainend"] = $his_target["endtime"];      // 添加时间字段
    //         $trade_analysis["train_shouyi"] = $his_target["year_shouyi"];// 添加时间字段
    //         $all_traget[] = $trade_analysis;
    //         ///////////////////////////////////
    //         $left_amount = (array)null;
    //         //////////////////////////
    //     }
    //     var_dump($trade_analysis);

    //     // 333333333333333333333333333333
    //     var_dump($incre_time); 
    //     //var_dump($incre_time < $End_Test);       

    //     $his_target = (array)null;           // 结果集置空
    //     $Sta_Test = $incre_time;             // 下一次训练的结束时间==下一次测试的开始时间
    //     // 获取第n次训练最佳指标
    //     $his_target = incremenOne($Sta_Test, $hold_time_array, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, NULL, $increment);
    //     $hold_time_parm =  $his_target["holdtime"];                    // 获取第n次训练最佳持股时间
    //     $incre_time = getDateByCur_After($Sta_Test, $hold_time_parm);  // 第n次的测试回测：结束时间

    //     $One_Trade  = (array)null;           // 第n-1次的结果集置空
    //     // 进行第n次的测试回测
    //     $One_Trade = oneActionMore($Sta_Test, $incre_time, $hold_time_parm, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, $left);
    //     $left = (array)null;
    //     $left = leftMore($Sta_Test, $incre_time, $One_Trade);         // 第n次测试回测的剩余持仓
    //     ////////////////////////////////
    //     $temp_amount = calculate_caption($One_Trade,$HoldLimit,$Sta_Test, $incre_time,$left_amount);
    //     $temp_amount = $temp_amount["two"];
    //     var_dump($left);
    //     var_dump($temp_amount);
    //     $left_amount = (array)null;   // 
    //     $left_amount = $temp_amount;
    //     $temp_amount = (array)null;
    //     ////////////////////////
    //     $trade_analysis = (array)null;       // 第n-1次的结果集置空
    //     if ($One_Trade != null)           // 需要有股票才进行投资
    //     {
            
    //         $trade_analysis = calTarget($One_Trade, $hold_time_parm,$HoldLimit,$Sta_Test, $incre_time,null);
    //         $trade_analysis["starttime"] = $Sta_Test;
    //         $trade_analysis["endtime"] = $incre_time;
    //         $trade_analysis["trainstart"] = $his_target["starttime"];  // 添加时间字段
    //         $trade_analysis["trainend"] = $his_target["endtime"];      // 添加时间字段
    //         $trade_analysis["train_shouyi"] = $his_target["year_shouyi"];// 添加时间字段
    //         $all_traget[] = $trade_analysis;
    //         ///////////////////////////////////
    //         $left_amount = (array)null;
    //         //////////////////////////
    //     }
    //     var_dump($trade_analysis);
        
    $train_fenxi = $all_traget;
    var_dump($train_fenxi );



    //////////////////////////////////////////
    // // 获取第一次最佳指标
    // $his_target = incremenOne($Sta_Test, $hold_time_array, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, NULL, $increment);
    // $hold_time_parm =  $his_target["holdtime"];                    // 第一次最佳持股时间
    // $incre_time = getDateByCur_After($Sta_Test, $hold_time_parm);  // 第一次测试：结束时间
    // // 进行第一次测试回测
    // $One_Trade = oneActionMore($Sta_Test, $incre_time, $hold_time_parm, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, NULL);
    // $left = leftMore($Sta_Test, $incre_time, $One_Trade);         // 第一次测试回测的剩余持仓
    // ///////////////////////////////////////////////////////////
    // // $left_amount = calculate_caption($One_Trade,$HoldLimit,$Sta_Test, $incre_time,null);
    // // $left_amount = $left_amount["two"];
    // // var_dump($left_amount);
    // ////////////////////////////////////////////////////////////////


    // // 判断第一次回测是否选到了一定数量的股票（若无，则无法计算指标）
    // if (count($One_Trade) > 2) {
    //     $trade_analysis = calTarget($One_Trade, $hold_time_parm,$HoldLimit,$Sta_Test, $incre_time,null);  // 计算第一次测试回测指标

    //     $trade_analysis["starttime"] = $Sta_Test;                  // 添加时间字段
    //     $trade_analysis["endtime"] = $incre_time;                  // 添加时间字段
    //     $trade_analysis["trainstart"] = $his_target["starttime"];  // 添加时间字段
    //     $trade_analysis["trainend"] = $his_target["endtime"];      // 添加时间字段
    //     $trade_analysis["train_shouyi"] = $his_target["year_shouyi"];// 添加时间字段
    //     $all_traget[] = $trade_analysis;                           // 保存指标
    // }
    // var_dump($End_Test);
    // while ($incre_time < $End_Test) {        // 第n次的测试回测的结束时间<输入的测试回测结束时间

    //     var_dump($incre_time);
        
    //     $his_target = (array)null;           // 结果集置空
    //     $Sta_Test = $incre_time;             // 下一次训练的结束时间==下一次测试的开始时间
    //     // 获取第n次训练最佳指标
    //     $his_target = incremenOne($Sta_Test, $hold_time_array, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, NULL, $increment);
    //     $hold_time_parm =  $his_target["holdtime"];                    // 获取第n次训练最佳持股时间
    //     $incre_time = getDateByCur_After($Sta_Test, $hold_time_parm);  // 第n次的测试回测：结束时间

    //     $One_Trade  = (array)null;           // 第n-1次的结果集置空
    //     // 进行第n次的测试回测
    //     $One_Trade = oneActionMore($Sta_Test, $incre_time, $hold_time_parm, $HoldLimit, $DayBuy, $KeepHoldProfit, $HighestFall, $StopLoseProfit, $orderRule, $left);
    //     $left = (array)null;
    //     $left = leftMore($Sta_Test, $incre_time, $One_Trade);         // 第n次测试回测的剩余持仓
    //     ////////////////////////////////
    //     // $temp_amount = calculate_caption($One_Trade,$HoldLimit,$Sta_Test, $incre_time,$left_amount);
    //     // $temp_amount = $temp_amount["two"];
    //     // var_dump($temp_amount);
    //     // $left_amount = (array)null;   // 
    //     // $left_amount = $temp_amount;
    //     // $temp_amount = (array)null;
    //     ////////////////////////
    //     $trade_analysis = (array)null;       // 第n-1次的结果集置空
    //     if (count($One_Trade) > 2)           // 需要有股票才进行投资
    //     {
            
    //         $trade_analysis = calTarget($One_Trade, $hold_time_parm,$HoldLimit,$Sta_Test, $incre_time,null);
    //         $trade_analysis["starttime"] = $Sta_Test;
    //         $trade_analysis["endtime"] = $incre_time;
    //         $trade_analysis["trainstart"] = $his_target["starttime"];  // 添加时间字段
    //         $trade_analysis["trainend"] = $his_target["endtime"];      // 添加时间字段
    //         $trade_analysis["train_shouyi"] = $his_target["year_shouyi"];// 添加时间字段
    //         $all_traget[] = $trade_analysis;
    //         ///////////////////////////////////
    //         // $left_amount = (array)null;
    //         //////////////////////////
    //     }
    // }
    // $train_fenxi = $all_traget;


   

















    /*********************************原来用于显示图表************************ */


    // // 计算折线图指标
    // $tempTotal = $One_HoldLimit_Trade;
    // // 每日市值结果的格式转换
    // $calDay  = calculate_caption($tempTotal);
    // foreach ($calDay as $key => $value) {
    //     $a = array((int)(strtotime($key) * 1000), $value);
    //     @$b[] = $a;
    // }
    // $arrayCalDay = array("day:$hold_time_parm" => @$b);
    // @$b = (array)null;
    // array_push($AllarrayCalDay, $arrayCalDay);


    // // 计算指标
    // $trade_analysis = calTarget($One_HoldLimit_Trade, $hold_time_parm, $tempTotal);
    // array_push($train_fenxi, $trade_analysis);   // 将所有的分析结果保存

    // // 计算饼图
    // $BingTu = calNumOfUpdownRate($One_HoldLimit_Trade);
    // $xx = array("day:$hold_time_parm" => $BingTu);
    // array_push($AllBingTu, $xx);

    // // 计算历史明细
    // $history = array("day:$hold_time_parm" => $One_HoldLimit_Trade);
    // array_push($AllHistory, $history);

    // // 明细的文件
    // $his_json_string  = json_encode($AllHistory);
    // // 饼状图
    // $bing_json_string  = json_encode($AllBingTu);
    // // 折线图
    // $AllLineChart2 = $AllarrayCalDay;
    // if ($compareWay != NULL)
    //     $zhishu = zhishuData($compareWay, $Sta_Test, $End_Test);

    // @$zhishutemp = array("zhishu" => $zhishu);
    // array_push($AllLineChart2, $zhishutemp);
    // $line_json_string  = json_encode($AllLineChart2);
}
